﻿using GeneticAlgorithms.Genomes;
using GeneticAlgorithms.Operators.Initialization;

namespace GeneticAlgorithms.Operators.Mutation
{
    /// <summary>
    /// Basic flip mutation operator. Works by just getting a new random value
    /// for each gene in the genome.
    /// </summary>
    /// <typeparam name="TGene">The type of the gene.</typeparam>
    public class FlipMutator<TGene> : BaseMutator<TGene>
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="FlipMutator&lt;TGene&gt;"/> class.
        /// </summary>
        public FlipMutator()
            : this(new SimpleInitializer<TGene>())
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FlipMutator&lt;TGene&gt;"/> class.
        /// </summary>
        /// <param name="initializer">The initializer.</param>
        public FlipMutator(IGeneticInitializer<TGene> initializer)
        {
            this.initializer = initializer;
        }

        /// <summary>
        /// Gene initializer.
        /// </summary>
        private IGeneticInitializer<TGene> initializer;

        /// <summary>
        /// Mutates a specific gene.
        /// </summary>
        /// <param name="genome">The genome whose gene will be mutated.</param>
        /// <param name="position">The gene position.</param>
        protected override void MutateGene(IGenome<TGene> genome, int position)
        {
            initializer.InitializeGene(genome, position);
        }
    }
}
